#ifndef __AT89S8253_H__
#define __AT89S8253_H__

register  char R0      absolute 0x00;
register  char R1      absolute 0x01;
register  char R2      absolute 0x02;
register  char R3      absolute 0x03;
register  char R4      absolute 0x04;
register  char R5      absolute 0x05;
register  char R6      absolute 0x06;
register  char R7      absolute 0x07;

/*
 * individual bit access constats
 */ 

// const char F0 = 0; // intentionally commented out
const char F1 = 1;
const char F2 = 2;
const char F3 = 3;
const char F4 = 4;
const char F5 = 5;
const char F6 = 6;
const char F7 = 7;

const char B0 = 0;
const char B1 = 1;
const char B2 = 2;
const char B3 = 3;
const char B4 = 4;
const char B5 = 5;
const char B6 = 6;
const char B7 = 7;

/*------------------------------------------------
Byte Registers
Note: Only Registers located on addresses that
are evenly divisible by 8 are bit addressable.
All other registers use bit masks.
------------------------------------------------*/
sfr char P0      absolute 0x80;     /* Port 0 */
sfr char SP      absolute 0x81;     /* Stack Pointer */
sfr char DPL     absolute 0x82;     /* Data Pointer Low Byte */
sfr char DP0L    absolute 0x82;     /* Alternate Definition */
sfr char DPH     absolute 0x83;     /* Data Pointer High Byte */
sfr char DP0H    absolute 0x83;     /* Alternate Definition */
sfr char DP1L    absolute 0x84;     /* Data Pointer 1 Low Byte , different to AT89C52 */
sfr char DP1H    absolute 0x85;     /* Data Pointer 1 High Byte , different to AT89C52 */
sfr char SPDR    absolute 0x86;     /* SPI Data Register , different to AT89C52 */
sfr char PCON    absolute 0x87;     /* Power Control Register */

sfr char TCON    absolute 0x88;     /* Timer Control Register */
sfr char TMOD    absolute 0x89;     /* Timer Mode Control Register */
sfr char TL0     absolute 0x8A;     /* Timer 0 Low Byte */
sfr char TL1     absolute 0x8B;     /* Timer 1 Low Byte */
sfr char TH0     absolute 0x8C;     /* Timer 0 High Byte */
sfr char TH1     absolute 0x8D;     /* Timer 1 High Byte */
sfr char AUXR    absolute 0x8E;     /* Auxiliary Register, DISALE */
sfr char CLKREG  absolute 0x8F;     /* Clock Register, X2 */

sfr char P1      absolute 0x90;     /* Port 1 */
sfr char EECON   absolute 0x96;     /* Memory Control Register */
sfr char SCON    absolute 0x98;     /* Serial Port Control */
sfr char SBUF    absolute 0x99;     /* Serial Port Buffer */

sfr char P2      absolute 0xA0;     /* Port 2 */
sfr char WDTRST  absolute 0xA6;     /* WDT Reset Register */
sfr char WDTCON  absolute 0xA7;     /* Watchdog Control Register */
sfr char IE      absolute 0xA8;     /* Interrupt Enable Register 0 */
sfr char SADDR   absolute 0xA9;     /* Enhanced UART Slave Address Register */
sfr char SPSR    absolute 0xAA;     /* SPI Status Register , different to AT89C52 */

sfr char P3      absolute 0xB0;     /* Port 3 */
sfr char IPH     absolute 0xB7;     /* Interrupt Priority High Register */
sfr char IP      absolute 0xB8;     /* Interrupt Priority Register */
sfr char SADEN   absolute 0xB9;     /* Enhanced UART Slave Address Mask Register */

sfr char T2CON   absolute 0xC8;     /* Timer 2 Control */
sfr char T2MOD	 absolute 0xC9;     /* Timer 2 Mode */
sfr char RCAP2L  absolute 0xCA;     /* Timer 2 Capture Low Byte */
sfr char RCAP2H  absolute 0xCB;     /* Timer 2 Capture High Byte */
sfr char TL2     absolute 0xCC;     /* Timer 2 Low Byte */
sfr char TH2     absolute 0xCD;     /* Timer 2 High Byte */

sfr char PSW     absolute 0xD0;     /* Program Status Word */
sfr char SPCR    absolute 0xD5;     /* SPI Control Register , different to AT89C52 */

sfr char ACC     absolute 0xE0;     /* Accumulator */

sfr char B       absolute 0xF0;     /* B Register */

/*------------------------------------------------
   Bit Variable Definitions
------------------------------------------------*/
/*------------------------------------------------
P0 (0x80) Bit Registers
------------------------------------------------*/
sbit sfr P0_0 at P0.B0;
sbit sfr P0_1 at P0.B1;
sbit sfr P0_2 at P0.B2;
sbit sfr P0_3 at P0.B3;
sbit sfr P0_4 at P0.B4;
sbit sfr P0_5 at P0.B5;
sbit sfr P0_6 at P0.B6;
sbit sfr P0_7 at P0.B7;

/*------------------------------------------------
TCON (0x88) Bit Registers
------------------------------------------------*/
sbit sfr IT0  at TCON.B0;       /* Interrupt 0 Type Control Bit */
sbit sfr IE0  at TCON.B1;       /* Interrupt 0 Edge Flag */
sbit sfr IT1  at TCON.B2;       /* Interrupt 1 Type Control Bit */
sbit sfr IE1  at TCON.B3;       /* Interrupt 1 Edge Flag */
sbit sfr TR0  at TCON.B4;       /* Timer 0 Run Control Bit */
sbit sfr TF0  at TCON.B5;       /* Timer 0 Overflow Flag */
sbit sfr TR1  at TCON.B6;       /* Timer 1 Run Control Bit */
sbit sfr TF1  at TCON.B7;       /* Timer 1 Overflow Flag */

/*------------------------------------------------
P1 (0x90) Bit Registers
------------------------------------------------*/
sbit sfr P1_0 at P1.B0;
sbit sfr P1_1 at P1.B1;
sbit sfr P1_2 at P1.B2;
sbit sfr P1_3 at P1.B3;
sbit sfr P1_4 at P1.B4;
sbit sfr P1_5 at P1.B5;
sbit sfr P1_6 at P1.B6;
sbit sfr P1_7 at P1.B7;

sbit sfr T2   at P1.B0;       /* External input to Timer/Counter 2, clock out */
sbit sfr T2EX at P1.B1;       /* Timer/Counter 2 capture/reload trigger & dir ctl */

sbit sfr SS   at P1.B4;       /* SPI: SS - Slave port select input */
sbit sfr MOSI at P1.B5;       /* SPI: MOSI - Master data output, slave data input */
sbit sfr MISO at P1.B6;       /* SPI: MISO - Master data input, slave data output */
sbit sfr SCK  at P1.B7;       /* SPI: SCK - Master clock output, slave clock input */

/*------------------------------------------------
SCON (0x98) Bit Registers
------------------------------------------------*/
sbit sfr RI   at SCON.B0;       /* Receive Interrupt Flag */
sbit sfr TI   at SCON.B1;       /* Transmit Interrupt Flag */
sbit sfr RB8  at SCON.B2;       /* 9th data bit received */
sbit sfr TB8  at SCON.B3;       /* 9th data bit to be transmitted in modes 2 & 3 */
sbit sfr REN  at SCON.B4;       /* Receive Enable */
sbit sfr SM2  at SCON.B5;       /* Serial Port Mode Bit 2 */
sbit sfr SM1  at SCON.B6;       /* Serial Port Mode Bit 1 */
sbit sfr SM0  at SCON.B7;       /* Serial Port Mode Bit 0 */

/*------------------------------------------------
P2 (0xA0) Bit Registers
------------------------------------------------*/
sbit sfr P2_0 at P2.B0;
sbit sfr P2_1 at P2.B1;
sbit sfr P2_2 at P2.B2;
sbit sfr P2_3 at P2.B3;
sbit sfr P2_4 at P2.B4;
sbit sfr P2_5 at P2.B5;
sbit sfr P2_6 at P2.B6;
sbit sfr P2_7 at P2.B7;

/*------------------------------------------------
IE (0xA8) Bit Registers
------------------------------------------------*/
sbit sfr EX0  at IE.B0;       /* External Interrupt 0 Enable: 1=Enabled */
sbit sfr ET0  at IE.B1;       /* Timer 0 Interrupt Enable: 1=Enabled */
sbit sfr EX1  at IE.B2;       /* External Interrupt 1 Enable: 1=Enabled */
sbit sfr ET1  at IE.B3;       /* Timer 1 Interrupt Enable: 1=Enabled */
sbit sfr ES   at IE.B4;       /* SPI and UART Interrupt Enable: 1=Enabled */
sbit sfr ET2  at IE.B5;       /* Timer 2 Interrupt Enable: 1=Enabled */

sbit sfr EA   at IE.B7;       /* Global Interrupt Enable: 0=Disable all interrupts */

/*------------------------------------------------
P3 (0xB0) Bit Registers (Mnemonics & Ports)
------------------------------------------------*/
sbit sfr P3_0 at P3.B0;
sbit sfr P3_1 at P3.B1;
sbit sfr P3_2 at P3.B2;
sbit sfr P3_3 at P3.B3;
sbit sfr P3_4 at P3.B4;
sbit sfr P3_5 at P3.B5;
sbit sfr P3_6 at P3.B6;
sbit sfr P3_7 at P3.B7;

sbit sfr RXD  at P3.B0;       /* Serial data input */
sbit sfr TXD  at P3.B1;       /* Serial data output */
sbit sfr INT0 at P3.B2;       /* External interrupt 0 */
sbit sfr INT1 at P3.B3;       /* External interrupt 1 */
sbit sfr T0   at P3.B4;       /* Timer 0 external input */
sbit sfr T1   at P3.B5;       /* Timer 1 external input */
sbit sfr WR   at P3.B6;       /* External data memory write strobe */
sbit sfr RD   at P3.B7;       /* External data memory read strobe */

/*------------------------------------------------
IP (0xB8) Bit Registers
------------------------------------------------*/
sbit sfr PX0  at IP.B0;       /* External Interrupt 0 Priority Bit */
sbit sfr PT0  at IP.B1;       /* Timer 0 Interrupt Priority Bit */
sbit sfr PX1  at IP.B2;       /* External Interrupt 1 Priority Bit */
sbit sfr PT1  at IP.B3;       /* Timer 1 Interrupt Priority Bit */
sbit sfr PS   at IP.B4;       /* Serial Port Interrupt Priority Bit */
sbit sfr PT2  at IP.B5;       /* Timer 2 Interrupt Priority Bit */

/*------------------------------------------------
T2CON (0xC8) Bit Registers
------------------------------------------------*/
sbit sfr CP_RL2 at T2CON.B0;      /* 0=Reload, 1=Capture select */
sbit sfr C_T2   at T2CON.B1;      /* 0=Timer, 1=Counter */
sbit sfr TR2    at T2CON.B2;      /* 0=Stop timer, 1=Start timer */
sbit sfr EXEN2  at T2CON.B3;      /* Timer 2 external enable */
sbit sfr TCLK   at T2CON.B4;      /* 0=Serial clock uses Timer 1 overflow, 1=Timer 2 */
sbit sfr RCLK   at T2CON.B5;      /* 0=Serial clock uses Timer 1 overflow, 1=Timer 2 */
sbit sfr EXF2   at T2CON.B6;      /* Timer 2 external flag */
sbit sfr TF2    at T2CON.B7;      /* Timer 2 overflow flag */

/*------------------------------------------------
PSW (0xD0) Bit Registers
------------------------------------------------*/
sbit sfr P    at PSW.B0;       /* Parity Flag */
sbit sfr FL   at PSW.B1;       /* User Flag */
sbit sfr OV   at PSW.B2;       /* Overflow Flag */
sbit sfr RS0  at PSW.B3;       /* Register Bank Select Bit 0 */
sbit sfr RS1  at PSW.B4;       /* Register Bank Select Bit 1 */
sbit sfr F0   at PSW.B5;       /* User Flag 0 */
sbit sfr AC   at PSW.B6;       /* Auxiliary Carry Flag */
sbit sfr CY   at PSW.B7;       /* Carry Flag */

/*------------------------------------------------
PCON (0x87) Bit Values
------------------------------------------------*/
const char SMOD1 = 7;
//Serial port Mode bit 1 for UART
//Set to select double baud rate in mode 1, 2 or 3.
const char SMOD0 = 6;
//Serial port Mode bit 0 for UART
//Cleared to select SM0 bit in SCON register.
//Set to select FE bit in SCON register.
//5 -
//Reserved
//The value read from this bit is indeterminate. Do not set this bit.
const char POF   = 4;
//Power-Off Flag
//Cleared to recognize next reset type.
//Set by hardware when VCC rises from 0 to its nominal voltage. Can also be set by software.
const char GF1   = 3;
//General purpose Flag
//Cleared by user for general purpose usage.
//Set by user for general purpose usage.
const char GF0   = 2;
//General purpose Flag
//Cleared by user for general purpose usage.
//Set by user for general purpose usage.
const char PD    = 1;
//Power-Down mode bit
//Cleared by hardware when reset occurs.
//Set to enter power-down mode.
const char IDL   = 0;
//Idle mode bit
//Cleared by hardware when interrupt or reset occurs.
//Set to enter idle mode.

/*------------------------------------------------
TMOD (0x89) Bit Values
------------------------------------------------*/
const char T0_M0   = 0;   /* Timer 0 Mode Bit 0 */
const char T0_M1   = 1;   /* Timer 0 Mode Bit 1 */
const char T0_CT   = 2;   /* Timer 0 Counter/Timer Select: 0=Timer, 1=Counter */
const char T0_GATE = 3;   /* Timer 0 Gate Control */

const char T1_M0   = 4;   /* Timer 1 Mode Bit 0 */
const char T1_M1   = 5;   /* Timer 1 Mode Bit 1 */
const char T1_CT   = 6;   /* Timer 1 Counter/Timer Select: 0=Timer, 1=Counter */
const char T1_GATE = 7;   /* Timer 1 Gate Control */

const char T1_MASK = 0xF0;   /* Timer 0 Mask */
const char T0_MASK = 0x0F;   /* Timer 1 Mask */

/*------------------------------------------------
AUXR (0x8E) Bit Values
------------------------------------------------*/
const char DISALE           = 0;   /* ALE management*/
const char Intel_Pwd_Exit   = 1;   /* Interrupt Driven Exit From Power-Down */

/*------------------------------------------------
CLKREG (0x8F) Bit Values
------------------------------------------------*/
const char X2           = 0;   /* Cscillator Frequency Devider*/

/*------------------------------------------------
EECON (0x96) Bit Values
------------------------------------------------*/
const char WRTINH  = 0;   /* Write Inhibit Flag*/
const char EERDY   = 1;   /* Watchdog Timer Reset and EEPROM Ready,/Busy Flag */
const char DPS     = 2;   /* Data Pointer Select: 0=DP0, 1=DP1 */
const char EEMEN   = 3;   /* Internal EEPROM Access Enable: 1=Enabled */
const char EEMWE   = 4;   /* Internal EEPROM Write Enable: 1=Enabled */
const char EELD    = 5;   /* EEPROM data memory load enable bit */

/*------------------------------------------------
WDTCON (0xA7) Bit Values
------------------------------------------------*/
const char WDTEN   = 0;   /* Watchdog software enable bit */
const char WDTRST_ = 1;   /* Watchdog Timer Reset Flag */
const char HWDT    = 2;   /* Hardware mode select for the WDT */
const char DISRTO  = 3;   /* Enable/disable the WDT-driven Reset Out */
const char WDIDLE  = 4;   /* Enable/disable the Watchdog Timer in IDLE mode */
const char PS0     = 5;   /* Prescaler bit 0 for the Watchdog Timer */
const char PS1     = 6;   /* Prescaler bit 1 for the Watchdog Timer */
const char PS2     = 7;   /* Prescaler bit 2 for the Watchdog Timer */
                          /* 000 =   16ms Timeout */
                          /* 001 =   32ms Timeout */
                          /* 010 =   64ms Timeout */
                          /* 011 =  128ms Timeout */
                          /* 100 =  256ms Timeout */
                          /* 101 =  512ms Timeout */
                          /* 110 = 1024ms Timeout */
                          /* 111 =  Timeout */

/*------------------------------------------------
SPSR (0xAA) Bit Values - Reset Value = 0000.01XX
------------------------------------------------*/
const char ENH   = 0;   /* Enhanced SPI mode select bit */
const char DISSO = 1;   /* Disable slave output bit */

const char LDEN  = 5;    /* Load enable for the Tx buffer in enhanced SPI mode */
const char WCOL  = 6;    /* ENH = 0: Write collision flag; ENH = 1: Tx Buffer Full */
const char SPIF  = 7;    /* SPI interrupt flag */

/*------------------------------------------------
IPH (0xB7) Bit Values - Reset Value = 0000.01XX
------------------------------------------------*/
const char PX0H = 0;    /* External Interrupt 0 Priority High */
const char PT0H = 1;    /* Timer 0 Interrupt Priority High */
const char PX1H = 2;    /* External Interrupt 1 Priority High */
const char PT1H = 3;    /* Timer 1 Interrupt Priority High */
const char PSH  = 4;    /* Serial Port Interrupt Priority High */
const char PT2H = 5;    /* Timer 2 Interrupt Priority High */

/*------------------------------------------------
T2MOD (0xC9) Bit Values
------------------------------------------------*/
const char DCEN = 0;    /* 1=Timer 2 can be configured as up/down counter */
const char T2OE = 1;    /* Timer 2 output enable */

/*------------------------------------------------
SPCR (0xD5) Bit Values - Reset Value = 0000.01XX
------------------------------------------------*/
const char SPR0 = 0;    /* SPI Clock Rate Select bit 0 */
const char SPR1 = 1;    /* SPI Clock Rate Select bit 1 */
                        /* 00 = Fosc / 4   */
                        /* 01 = Fosc / 16  */
                        /* 10 = Fosc / 64  */
                        /* 11 = Fosc / 128 */

const char CPHA = 2;    /* SPI Clock Phase */
const char CPOL = 3;    /* SPI Clock Polarity */
const char MSTR = 4;    /* SPI Master/Slave Select: 0=Slave, 1=Master */
const char DORD = 5;    /* SPI Data Order: 0=MSB First, 1=LSB First */
const char SPE  = 6;    /* SPI Enable: 0=Disabled, 1=Enabled */
const char SPIE = 7;    /* SPI Interrupt Enable: 0=Disabled, 1=Enabled */

/*------------------------------------------------
Interrupt Vectors:
Interrupt Address = (Number * 8) + 3
------------------------------------------------*/
const char IE0_VECTOR	= 0;  /* 0x03 External Interrupt 0 */
const char TF0_VECTOR	= 1;  /* 0x0B Timer 0 */
const char IE1_VECTOR	= 2;  /* 0x13 External Interrupt 1 */
const char TF1_VECTOR	= 3;  /* 0x1B Timer 1 */
const char SIO_VECTOR	= 4;  /* 0x23 Serial port */

const char TF2_VECTOR	= 5;  /* 0x2B Timer 2 */
const char EX2_VECTOR	= 5;  /* 0x2B External Interrupt 2 */

#endif
